package cn.iocoder.yudao.framework.license;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.concurrent.TimeUnit;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 *  这里是文件说明
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2025/04/05
 */
@EnableScheduling
@AutoConfiguration
@ConditionalOnProperty(prefix = "xianmin.developer", name = "license-verify", havingValue = "true")
public class LicenseAutoConfiguration {
    private static boolean LICENSE_IS_AVAILABLE = false;
    private static int FAIL_NUM = 0;
    private static final int FAIL_MAX_NUM = 10;

    public LicenseAutoConfiguration() {
        try {
            loadLicense();
        } catch (Exception ignore) {
        }
    }

    @Bean
    public FilterRegistrationBean<LicenseCheckFilter> licenseCheckFilter() {
        FilterRegistrationBean<LicenseCheckFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new LicenseCheckFilter());
        registrationBean.addUrlPatterns("/admin-api/*");
        registrationBean.setOrder(1);
        return registrationBean;
    }

    /**
     * 固定间隔几分钟检加载一次许可证
     */
    @Scheduled(fixedDelay = 60, initialDelay = 5, timeUnit = TimeUnit.MINUTES)
    public void loadLicense() {
        // 连续多次次请求出现许可失败，则直接返回失败不再加载许可证文件。
        if (FAIL_NUM >= FAIL_MAX_NUM) {
            return;
        }
        // 当授权验证为false时，进行重新验证，让前十次验证时即使没有授权也能成功，直到连续失败十次
        if (!LICENSE_IS_AVAILABLE) {
            try {
                LicenseHandler.checkLicense();
                LICENSE_IS_AVAILABLE = true;
                FAIL_NUM = 0;
            } catch (Exception e) {
                LICENSE_IS_AVAILABLE = false;
                FAIL_NUM++;
            }
        }
    }

}
